﻿#include "PlatformProperty.h"
#define AUTO_STEERING_WHEEL_HEAT_OFF 0
#define AUTO_STEERING_WHEEL_HEAT_LOW 1
#define AUTO_STEERING_WHEEL_HEAT_MID 2
#define AUTO_STEERING_WHEEL_HEAT_HIGH 3

#define MSG_STEERING_WHEEL_HEAT_RESPONSE_1 1
#define MSG_STEERING_WHEEL_HEAT_RESPONSE_2 2
#define HVAC_HVAC_STEERING_WHEEL_HEAT_DELAY 3 * 1000

namespace ecarx::vhal::core::property::impl { class VehiclePropertyHVAC_STEERING_WHEEL_HEAT; }
bool isECO = false;
bool isDyno = false;
bool isModCnvinc = false;

void openVFC(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_STEERING_WHEEL_HEAT* thisPtr);

SYSTEM_READ_WRITE_PROPERTY(HVAC_STEERING_WHEEL_HEAT, int32_t) {
    builder.area(VehicleArea::GLOBAL)
        .initValue([]() { return AUTO_STEERING_WHEEL_HEAT_OFF; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& lastStatus) {
                if (SIGNAL.carConfigIs(SignalRX::carconfig186, sdb::CarConfig186::_02)) {
                    if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04) &&
                        (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg) ||
                         SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModActv) ||
                         SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)) &&
                        (SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm) ||
                         SIGNAL.carModeIs(sdb::CarModSts1::CarModDyno))) {
                        auto steeringWheelHeatgAvlSts = SIGNAL.getSteerWhlHeatgAvlSts();
                        if (steeringWheelHeatgAvlSts == sdb::StsFd::Error ||
                            steeringWheelHeatgAvlSts == sdb::StsFd::Energylimit) {
                            VHALOG.e("HVAC_STEERING_WHEEL_HEAT global steeringWheelHeatgAvlSts[%d] status changed to: NotActive ",steeringWheelHeatgAvlSts);
                            return PropertyStatus::NotActive;
                        }
                        VHALOG.d("HVAC_STEERING_WHEEL_HEAT global cc13=04 status changed to: Active ");
                        if(SIGNAL.carModeIs(sdb::CarModSts1::CarModDyno)){
                            if(!isDyno){
                                //信号发生变化，VFC 开启
                                if(SIGNAL.getSteerWhlHeatgAvlSts() != sdb::StsFd::Off){
                                    openVFC(this);
                                    SIGNAL.setSteerWhlHeatgOnReq(sdb::SteerWhlHeatgOnCmdTyp::Off);
                                }
                            }
                            isDyno = true;
                        }else{
                            isDyno = false;
                        }
                        if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)){
                            isModCnvinc = true;
                        }else{
                            if(isModCnvinc){
                                VHALOG.d("HVAC_STEERING_WHEEL_HEAT setCB_VFC_SteerWhlHeatgCtrlForHmiCenPDC off ");
                                SIGNAL.setCB_VFC_SteerWhlHeatgCtrlForHmiCenPDC(sdb::OnOff1::Off);
                            }
                            isModCnvinc = false;
                        }
                        return PropertyStatus::Active;
                    }
                    VHALOG.d("HVAC_STEERING_WHEEL_HEAT global status changed to: NotActive ");
                    return PropertyStatus::NotActive;
                }
                VHALOG.d("HVAC_STEERING_WHEEL_HEAT global cc186!=02 status changed to: NotAvailable ");
                return PropertyStatus::NotAvailable;
            },
            SignalRX::carconfig186, SignalRX::carconfig13, SignalRX::SteerWhlHeatgAvlSts,
            SignalRX::VehModMngtGlbSafe1UsgModSts, SignalRX::VehModMngtGlbSafe1CarModSts1)
        .withValueBySignals(
            [this]([[maybe_unused]] const int32_t& last) {
                removeMsg(MSG_STEERING_WHEEL_HEAT_RESPONSE_1);
                if (SIGNAL.getSteerWhlHeatgAvlSts() == sdb::StsFd::Error) {
                    VHALOG.d("HVAC_STEERING_WHEEL_HEAT  Error value changed to:Off");
                    return AUTO_STEERING_WHEEL_HEAT_OFF;
                }
                int32_t sSteerWhlHeatgLvlSts = toInt(SIGNAL.getSteerWhlHeatgLvlSts());
                int32_t res = AUTO_STEERING_WHEEL_HEAT_OFF;
                switch(sSteerWhlHeatgLvlSts){
                    case toInt(sdb::SteerWhlHeatgOnCmdTyp::Off):
                        res = AUTO_STEERING_WHEEL_HEAT_OFF;
                        break;
                    case toInt(sdb::SteerWhlHeatgOnCmdTyp::Lo):
                        res = AUTO_STEERING_WHEEL_HEAT_LOW;
                        break;
                    case toInt(sdb::SteerWhlHeatgOnCmdTyp::Med):
                        res = AUTO_STEERING_WHEEL_HEAT_MID;
                        break;
                    case toInt(sdb::SteerWhlHeatgOnCmdTyp::Hi):
                        res = AUTO_STEERING_WHEEL_HEAT_HIGH;
                        break;
                    default:
                        break;
                }
                VHALOG.d("HVAC_STEERING_WHEEL_HEAT Valve Change res:[%d]", res);
                return res;
            },
            SignalRX::SteerWhlHeatgAvlSts, SignalRX::SteerWhlHeatgLvlSts)
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("halOnSetProperty HVAC_STEERING_WHEEL_HEAT : %d", value);
            if(value != AUTO_STEERING_WHEEL_HEAT_OFF
                    && value != AUTO_STEERING_WHEEL_HEAT_LOW
                    && value != AUTO_STEERING_WHEEL_HEAT_MID
                    && value != AUTO_STEERING_WHEEL_HEAT_HIGH){
                        return;
            }
            removeMsg(MSG_STEERING_WHEEL_HEAT_RESPONSE_1);
            sdb::SteerWhlHeatgOnCmdTyp steerWhlHeatgReq = sdb::SteerWhlHeatgOnCmdTyp::Off;
            if (value == AUTO_STEERING_WHEEL_HEAT_OFF) {
                steerWhlHeatgReq = sdb::SteerWhlHeatgOnCmdTyp::Off;
            } else if (value == AUTO_STEERING_WHEEL_HEAT_LOW) {
                steerWhlHeatgReq = sdb::SteerWhlHeatgOnCmdTyp::Lo;
            } else if (value == AUTO_STEERING_WHEEL_HEAT_MID) {
                steerWhlHeatgReq = sdb::SteerWhlHeatgOnCmdTyp::Med;
            } else if (value == AUTO_STEERING_WHEEL_HEAT_HIGH) {
                steerWhlHeatgReq = sdb::SteerWhlHeatgOnCmdTyp::Hi;
            }
            openVFC(this);
            SIGNAL.setSteerWhlHeatgOnReq(steerWhlHeatgReq);
            setValue(toInt(VehicleArea::GLOBAL), value);
            sendMsg(MSG_STEERING_WHEEL_HEAT_RESPONSE_1, HVAC_HVAC_STEERING_WHEEL_HEAT_DELAY);
        })
        .onPropertyValueChange(
            ECarXVehicleProperty::DM_FUNC_DRIVE_MODE_SELECT, VehicleArea::GLOBAL,
            [this](const VehiclePropValue& value) {
                auto drvMod = getPropertyValue<DriveModeSelection>(
                    static_cast<int32_t>(ECarXVehicleProperty::DM_FUNC_DRIVE_MODE_SELECT),
                    static_cast<int32_t>(VehicleArea::GLOBAL));
                VHALOG.d("HVAC_STEERING_WHEEL_HEAT halOnPropertyValueChange  DrvModReq: %d", drvMod);

                if (drvMod == DriveModeSelection::DRIVE_MODE_SELECTION_ECO) {  // DrvModReq ==ECO模式
                    if(!isECO){
                        //信号发生变化，VFC 开启
                        if(SIGNAL.getSteerWhlHeatgAvlSts() != sdb::StsFd::Off){
                            openVFC(this);
                            SIGNAL.setSteerWhlHeatgOnReq(sdb::SteerWhlHeatgOnCmdTyp::Off);
                        }
                    }
                    isECO = true;
                }else{
                    isECO = false;
                }
            })
        .onMsgEvent(MSG_STEERING_WHEEL_HEAT_RESPONSE_1, [this]() {
            // 3s后根据反馈信号更新
            sdb::SteerWhlHeatgOnCmdTyp sdbValue = SIGNAL.getSteerWhlHeatgLvlSts();
            int32_t cmpPaValue = toInt(sdbValue);
            int32_t paValue = getValue(toInt(VehicleArea::GLOBAL));
            VHALOG.d(
                "HVAC_STEERING_WHEEL_HEAT onMsgEvent: MSG_STEERING_WHEEL_HEAT_RESPONSE_1 checkValue "
                "paValue[%d], cmpPaValue[%d], sdbValue[%d]",
                paValue, cmpPaValue, sdbValue);
            // 如果反馈信号和PA不一样 那么就更新PA
            if (paValue != cmpPaValue) {
                setValue(toInt(VehicleArea::GLOBAL), cmpPaValue);
                VHALOG.d(
                    "HVAC_STEERING_WHEEL_HEAT onMsgEvent: MSG_STEERING_WHEEL_HEAT_RESPONSE_1 checkValue "
                    "not equal!");
                openVFC(this);
                SIGNAL.setSteerWhlHeatgOnReq(sdbValue);
            }
        })
        .onMsgEvent(MSG_STEERING_WHEEL_HEAT_RESPONSE_2, []() {
            // 3s后关闭VFC
            VHALOG.d("HVAC_STEERING_WHEEL_HEAT onMsgEvent MSG_STEERING_WHEEL_HEAT_RESPONSE_2");
            VHALOG.d("HVAC_STEERING_WHEEL_HEAT setCB_VFC_SteerWhlHeatgCtrlForHmiCenPDC off ");
            SIGNAL.setCB_VFC_SteerWhlHeatgCtrlForHmiCenPDC(sdb::OnOff1::Off);
        });
}
void openVFC(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_STEERING_WHEEL_HEAT* thisPtr){
    if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)) {
        thisPtr->removeMsg(MSG_STEERING_WHEEL_HEAT_RESPONSE_2);
        VHALOG.d("HVAC_STEERING_WHEEL_HEAT : setCB_VFC_SteerWhlHeatgCtrlForHmiCenPDC on ");
        SIGNAL.setCB_VFC_SteerWhlHeatgCtrlForHmiCenPDC(sdb::OnOff1::On);
        thisPtr->sendMsg(MSG_STEERING_WHEEL_HEAT_RESPONSE_2, HVAC_HVAC_STEERING_WHEEL_HEAT_DELAY);
    }
}
